import MonacoEditor, { OnMount, OnValidate } from "@monaco-editor/react";
import { useComponentsStore } from "@/stores/edit-pages-store";
import { useEffect, useRef, useState } from "react";
import { Modal, notification } from "antd";
import { CloseCircleFilled } from "@ant-design/icons";
import { debounce, isEqual } from "lodash-es";
import { useGetState } from "ahooks";
import { checkComponentsAllValid, checkLineWithoutArrField } from "./source-edit-methods";
import type { editor } from "monaco-editor";
import { setCustomClassStylesheet, setThemeCssClassStylesheet } from "@/pages/lowCodeEditorPlus/utils/styleOperation";

type ValidateParams = Parameters<OnValidate>[0];
type EditorRef = Parameters<OnMount>[0];

export function Source() {
  const { schema, curComponent, curComponentId, updateFullComponent } = useComponentsStore();
  const [value, setValue] = useState("");

  const [editorErrors, setEditorErrors, getEditorErrors] = useGetState<ValidateParams>([]);
  const editorRef = useRef<EditorRef>();
  const [blurState, setBlurState] = useState(false);

  /**更新值*/
  const updateValue = ()=>{
    const component = curComponentId ? curComponent : schema;
    setValue(JSON.stringify(component, null, 2));
  }

  useEffect(() => {
    updateValue()
  }, [curComponentId]);

  useEffect(() => {
    const unsubscribe = useComponentsStore.subscribe((state) => {
      if(value !=="" && JSON.stringify(state.curComponent)!==JSON.stringify(value)){
        setValue(JSON.stringify(state.curComponent, null, 2));
      }
    });

    return () => unsubscribe();
  }, [value]);

  /**监测语法错误*/
  useEffect(() => {
    checkWhileFormatError(blurState);
  }, [blurState]);
  const handleEditorMount: OnMount = (editor, monaco) => {
    editorRef.current = editor;
    editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyJ, () => {
      editor.getAction("editor.action.formatDocument")?.run();
    });
    editor.onDidBlurEditorWidget(() => {
      setBlurState(false);
    });
    editor.onDidFocusEditorWidget(() => {
      setBlurState(true);
    });
  };
  
  const [noteApi, noteContextHolder] = notification.useNotification();
  const handleEditorChange = debounce((editValue, event: editor.IModelContentChangedEvent) => {
    const errors = getEditorErrors();

    if (errors.length > 0) {
      //语法格式检查
      const error = errors[0];
      const {startLineNumber,startColumn,message} = error
      setTimeout(() => {
        noteApi.warning({
          message: "代码有误",
          description:`行${startLineNumber}， 列${startColumn}，${message}`,
          placement:"topRight"
        });
      }, 3000);
    } else {
      /* 改动字段检查，禁用[id,desc,name]*/
      const disableFields = ["id", "desc", "name", "parentId"];
      const model = editorRef.current?.getModel()!;
      const isValid = event.changes.some(item=>{
        const {startLineNumber} = item.range
        const editLineText = model.getLineContent(startLineNumber)!
        return checkLineWithoutArrField(editLineText, disableFields)
      })
      
      if(!isValid){
        noteApi.warning({
          message: "警告",
          description:`${disableFields.join("; ")} 字段禁止编辑`,
          placement:"topRight"
        });
        // editorRef.current?.trigger("external", "undo", undefined)
        editorRef.current?.trigger("external", "redo", undefined)
        return
      }

      /*检查是否缺失字段*/
      const comp = JSON.parse(editValue)
      const compOk = checkComponentsAllValid(comp, disableFields)
      if(!compOk){
        noteApi.warning({
          message: "警告",
          description:`${disableFields.join("; ")} 字段不可删除`,
          placement:"topRight"
        });
        // editorRef.current?.trigger("external", "undo", undefined)
        return
      }

      /*校验通过后执行*/
      /*自定义样式更新*/
      if(!isEqual(curComponent?.customClassStyle, comp?.customClassStyle)){
        setCustomClassStylesheet({
          style:comp.customClassStyle,
          id:comp.id,
        })
      }
      /*增选样式更新*/
      if (!isEqual(curComponent?.themeCss, comp?.themeCss)) {
        setThemeCssClassStylesheet({
          style: comp.themeCss,
          id: comp.id,
        })
      }
      updateFullComponent(comp)
    }
  },1000)
  const handleValidate = (markers: ValidateParams) => {
    setEditorErrors(markers);
  };
  const checkWhileFormatError = (state: boolean) => {
    const len = editorErrors.length;
    if (!state && len > 0) {
      setIsModalOpen(true);
    }
  };

  const [isModalOpen, setIsModalOpen] = useState(false);
  const handleOk = () => {
    editorRef.current?.trigger("external", "undo", undefined)
    setIsModalOpen(false);
  };
  const handleCancel = () => {
    setIsModalOpen(false);
  };
  return (
    <>
      <MonacoEditor
        height={"100%"}
        // path="light"
        language="json"
        onMount={handleEditorMount}
        value={value}
        onChange={handleEditorChange}
        onValidate={handleValidate}
        options={{
          fontSize: 12,
          scrollBeyondLastLine: false,
          minimap: {
            enabled: false,
          },
          scrollbar: {
            verticalScrollbarSize: 6,
            horizontalScrollbarSize: 6,
          },
        }}
      />
      <Modal
        open={isModalOpen}
        onOk={handleOk}
        onCancel={handleCancel}
        okButtonProps={{ danger: true }}
        title={
          <div className="flex items-center gap-x-3">
            <CloseCircleFilled className="text-red-500 text-2xl" />
            <span>请确认</span>
          </div>
        }
        styles={{ body: { marginInlineStart: "36px" } }}
      >
        <p>当前有部分已更改数据因为格式不正确尚未保存，您确认要撤销这部分更改吗？</p>
      </Modal>
      {noteContextHolder}
    </>
  );
}
